#include "wcsreciver.h"

#include "componentmanager.h"
#include "systemconfiguration.h"
#include "../../HttpServer/httpserver.h"
#include "component_log.h"
#include "json_trans.h"
#include "componentmanager.h"
#include "../grating/grating_data.h"


structJ(AnsMsg,
	mapping(int, code);
mapping(QString, msg);
prop(&code, &msg);
);

WCSReciver::WCSReciver(QObject* parent)
	: ComponentBase(parent)
{
	m_errmsg = "";
	m_name = u8"wcs消息接收组件";
	m_type = Component::component_wcsrec;
}

WCSReciver::~WCSReciver()
{}

// 订阅接口，提供给其它组件订阅本组件消息的接口
bool WCSReciver::RegisterSubscriberFunction(int type, Callback callback)
{
	if (type < 1 || type >(int)WCSMsgType::wcs_msg_max) {
		log_error("RegisterSubscriberFunction type [{}] error", type);
		return false;
	}
	WCSMsgType mType = (WCSMsgType)type;
	auto iter = m_subscribers.find(mType);
	if (iter == m_subscribers.end()) {
		QVector<std::function<int(const QByteArray&)>> temp;
		temp.append(callback);
		m_subscribers.insert(mType, temp);
	} else {
		iter.value().append(callback);
	}
	return true;
}

// 组件初始化处理函数
int WCSReciver::ComponentInit()
{
	auto cfg = syscfg->GetWcsCfg();
	m_server = new HttpServer(nullptr);
	int ret = m_server->StartSever(cfg.robIP, cfg.robPort);
	if (ret != 0) {
		switch (ret) {
		case -1:
			SetErrmsg("参数异常，WCS服务启动失败");
			break;
		default:
			SetErrmsg("WCS服务启动失败", false);
			break;
		}
		return -99;
	}
	auto func = [&](const QString& type, const QByteArray& req, QByteArray& ans) {
		return ReciverMsg(type, req, ans);
	};
	m_server->RegisterServerFunc(func);

	m_stackInfo = component->GetComponent(Component::component_stackInfo);
	if (m_stackInfo == nullptr) {
		SetErrmsg("码垛垛形管理组件获取失败", false);
		return -99;
	}

	m_grating = component->GetComponent(Component::component_grating);
	if (m_grating == nullptr) {
		log_error("未获取到光栅组件，光栅通信功能失效");
	}

	log_trace("wcs recive component  init success");
	return 0;
}
/*自检接口*/
bool WCSReciver::ComponentCheckSelfState()
{
	if (m_server->IsListening()) {
		return true;
	}
	SetErrmsg("WCS服务已经关闭，无法接收任务数据", false);
	return false;
}
/*复位接口*/
bool WCSReciver::ComponentSelfReset()
{
	if (m_server->IsListening()) {
		return true;
	}
	if (m_server->ReStartSever() == 0) {
		return true;
	} else {
		SetErrmsg("重启WCS服务失败，无法接收任务数据", false);
		return false;
	}
}

int WCSReciver::ReciverMsg(const QString& path, const QByteArray& req, QByteArray& ans)
{
	QStringList paths = path.split("/");
	if (paths.size() > 2 && paths.at(0) == "grating") {
		return GratingProcess(path, req, ans);
	} else {
		return WCSMsgProcess(path, req, ans);
	}
}
/*获取命令编码*/
WCSMsgType WCSReciver::GetWCSCmdNum(const QString& type, MethodType method)
{
	std::map<QString, WCSMsgType> PostCmdMapping = {
	{"/plate/arrived", WCSMsgType::wcs_msg_plate_arrive},
	{"boxLineInfo", WCSMsgType::wcs_msg_boxline},
	{"/plate/moved", WCSMsgType::wcs_msg_plate_move},
	{"/task/taskInfo", WCSMsgType::wcs_msg_task},
	{"stackInfo", WCSMsgType::wcs_msg_stackInfo},
	};

	if (method == MethodType::method_post) {
		auto iter = PostCmdMapping.find(type);
		if (iter != PostCmdMapping.end()) {
			return (iter->second);
		} else {
			return WCSMsgType::wcs_msg_max;
		}
	} else {
		return WCSMsgType::wcs_msg_max;
	}
}

GratingMsgType WCSReciver::GetGratingCmdNum(const QString& type, MethodType method)
{
	std::map<QString, GratingMsgType> PostCmdMapping = {
	{"/grating/status", GratingMsgType::grating_state_info},
	{"/grating/change", GratingMsgType::grating_change_state},
	};

	if (method == MethodType::method_post) {
		auto iter = PostCmdMapping.find(type);
		if (iter != PostCmdMapping.end()) {
			return (iter->second);
		} else {
			return GratingMsgType::grating_cmd_max;
		}
	} else {
		return GratingMsgType::grating_cmd_max;
	}
}

structJ(AnsTask,
	mapping(QString, taskId);
prop(&taskId);
);

structJ(AnsMove,
	mapping(QString, stackPlace);
prop(&stackPlace);
);
structJ(AnsLineState,
	mapping(QString, boxLine);
mapping(int, posId);
prop(&boxLine, &posId);
)

int WCSReciver::WCSMsgProcess(const QString& cmd, const QByteArray& data, QByteArray& ans)
{
	WCSMsgType type = GetWCSCmdNum(cmd, MethodType::method_post);
	if (type >= WCSMsgType::wcs_msg_max || type < WCSMsgType::wcs_msg_task) {
		ans = CreateAnsData(-1, "路径未匹配到处理程序", {});
		return server_path_err;
	}
	int ret = 0;
	QByteArray ansData;
	switch (type) {
	case WCSMsgType::wcs_msg_task:
	case WCSMsgType::wcs_msg_plate_arrive:
	{
		AnsTask an = {};
		an.fromJson(data);
		ansData = an.toByteArray();
	}
	break;
	case WCSMsgType::wcs_msg_plate_move:
	{
		AnsMove an = {};
		an.fromJson(data);
		ansData = an.toByteArray();
	}
	break;
	case WCSMsgType::wcs_msg_boxline:
	{
		AnsLineState an = {};
		an.fromJson(data);
		ansData = an.toByteArray();
	}
	break;
	case WCSMsgType::wcs_msg_stackInfo:
	{
		QByteArray usrData;
		if (m_stackInfo->ExcuteCmd(1, data, usrData)) {
			ans = CreateAnsData(0, "0", usrData);
			return server_ok;
		}
		ans = CreateAnsData(0, "未匹配到垛形", usrData);
		return server_common_err;
	}
	break;
	default:
		return server_path_err;
		break;
	}

	bool OkFlag = false;
	if (m_subscribers.contains(type)) {
		for (auto iter : m_subscribers.value(type)) {
			ret = iter(data);
			if (ret == 0) {
				OkFlag = true;
			}
		}
	}
	if (OkFlag) {
		ans = CreateAnsData(0, "", ansData);
		return server_ok;
	} else {
		ans = CreateAnsData(-1, "消息处理异常", ansData);
		return server_common_err;
	}
}
int WCSReciver::GratingProcess(const QString& cmd, const QByteArray& req, QByteArray& ans)
{
	if (m_grating == nullptr) {
		ans = CreateAnsData(-1, "机械手光栅功能未启用", {});
		return -1;
	} else {
		QByteArray usrdata;
		GratingMsgType type = GetGratingCmdNum(cmd, MethodType::method_post);
		switch (type) {
		case GratingMsgType::grating_state_info:
			if (m_grating->ExcuteCmd((int)GratingCmdType::get_grating_able_state, req, usrdata)) {
				ans = CreateAnsData(0, "", usrdata);
			} else {
				ans = CreateAnsData(-1, "状态获取失败", usrdata);
			}
			break;
		case GratingMsgType::grating_change_state:
			if (m_grating->ExcuteCmd((int)GratingCmdType::set_grating_able_state, req, usrdata)) {
				ans = CreateAnsData(0, "", usrdata);
			} else {
				ans = CreateAnsData(-1, "状态设置失败", usrdata);
			}
			break;
		default:
			ans = CreateAnsData(-1, "错误的命令类型", {});
			break;
		}
	}
	return 0;
}


QByteArray WCSReciver::CreateAnsData(int code, const QString& msg, const QByteArray& usrData)
{
	AnsMsg ans = {};
	ans.code = code;
	ans.msg = msg;
	QJsonObject json = ans.toJson();
	QJsonDocument usr = QJsonDocument::fromJson(usrData);
	json["data"] = usr.object();
	QJsonDocument doc(json);
	return doc.toJson();
}
